
#include<iostream>
#include<osgText/Text>
#include "callback.h"

using namespace std;

/* Constructor: Node callback object. */
CBTreeInsert::CBTreeInsert(DataContainer& input, BinaryTreeType type)
{
	this->input = input; 
	this->count = 0;  
	this->tree_type = type;
	this->btroot = NULL;
	this->start_tick = osg::Timer::instance()->tick();
	if(tree_type == SIMPLE)
		cout << "Animating simple binary search tree. " << endl;
	else if(tree_type == REDBLACK)
		cout << "Animating Red-Black binary search tree. " << endl;
} 

/* Insert and draw new tree node every few secs, till 
* input is finished. */
void CBTreeInsert::operator()(osg::Node * node, osg::NodeVisitor * nv)
{
	osg::Timer_t end_tick = osg::Timer::instance()->tick();
	double delta_s = osg::Timer::instance()->delta_s(start_tick, end_tick);

	/* Pause for T seconds. Stop after all input is processed. */
	if((delta_s > 1.0) && (count < (int)input.size())) {

		BinaryTreeNode * btnode = new BinaryTreeNode(input[count]);

		/* 1. Add new node to correct place in binary tree. 
		 * this will create new version of the binary tree. */
		if(tree_type == SIMPLE)
			BinaryTreeNode::insert(btroot, btnode);
		else if(tree_type == REDBLACK)
			BinaryTreeNode::rb_insert(btroot, btnode);

		/* 2. Get hold of group. */
		osg::Group * p_group = dynamic_cast<osg::Group*>(node);
		osg::Geode * p_geode;

		/* 2.1. Get hold of input geode. */
		p_geode = dynamic_cast<osg::Geode*>(p_group->getChild(0));
		osg::ref_ptr<osg::Geode> input_geode(p_geode);
		osgText::Text * p_text;
	   	p_text = dynamic_cast<osgText::Text*>(input_geode->getDrawable(count));
		p_text->setCharacterSize(1.4);
		if(count != 0) {
	   		p_text = dynamic_cast<osgText::Text*>(input_geode->getDrawable(count-1));
			p_text->setCharacterSize(0.6);
		}

		/* 2.2. Get hold of tree geode. */
	   	p_geode = dynamic_cast<osg::Geode*>(p_group->getChild(1));
		osg::ref_ptr<osg::Geode> tree_geode(p_geode);

		/* 4. Delete drawables representing old version of binary tree */
		tree_geode->removeDrawables(0, tree_geode->getNumDrawables());

		/* 5. Re-create new drawable for new version binary tree. */
		btroot->tree_draw(tree_geode);

		start_tick = osg::Timer::instance()->tick();
		count++;
	}

	/* Draw traversal of remaining SG. */
	traverse(node, nv);
}

